//
// Created by tacom on 2022/8/22.
//

#include "vascular.h"

pybind11::array_t<unsigned char> vascular::hilditch(pybind11::array_t<unsigned char> &input) {
    cv::Mat inputMat = NumPyMatConvert::Ny8UC3ToMat(input);

    try{
        return hilditch::hilditchStart(inputMat);
    }catch (const std::exception& e){
        std::cout << e.what() << std::endl;
        return pybind11::array_t<unsigned char>();
    }
}


std::pair<pybind11::array_t<unsigned char>, std::vector<unsigned>>
vascular::CNFD(
        pybind11::array_t<unsigned char> &input,
        std::vector<std::vector<int>> &matrixShape,
        std::vector<unsigned int> &resultList,
        int height, int width, int stride
) {
    cv::Mat inputMat = NumPyMatConvert::Ny8UC3ToMat(input);

    try{
        return std::make_pair(
                this->CNFDStart(inputMat, matrixShape, resultList, height, width, stride),
                resultList
                );
    }catch (const std::exception& e){
        std::cout << e.what() << std::endl;
        return std::make_pair(
                pybind11::array_t<unsigned char>(),
                resultList
                );
    }
}

pybind11::array_t<unsigned char> vascular::CNFDStart(
        cv::Mat &input,
        std::vector<std::vector<int>> &matrixShape,
        std::vector<unsigned int> &resultList,
        int height, int width, int stride
) {
    cv::cuda::GpuMat src, dst;
    src.upload(input);

    CNFDCudaWrapper(src, dst, height, width, stride, matrixShape, resultList);

    cv::Mat down;
    dst.download(down);
    return NumPyMatConvert::Mat8UC3ToNumpy(down);
}

intersection::INTERSECTIONS vascular::Intersection(vascular::CV_ARRAY &input) {
    cv::Mat inputMat = NumPyMatConvert::Ny8UC1ToMat(input);

    try{
        return this->sectionPredictor.GetSkeletonIntersection(inputMat);
    }catch (const std::exception& e){
        std::cout << e.what() << std::endl;
        return intersection::INTERSECTIONS {};
    }
}

CTBD::CTBD_LIST
vascular::CTBDWrapper(vascular::CV_ARRAY &input, vascular::USABLE_MATRIX &matrixShape,
                      int height, int width, int stride, CTBD::FILE_NAME_LIST &fileNameList,
                      CTBD::FILE_PATH &refineSavePath, CTBD::FILE_PATH &segSavePath) {
    cv::Mat inputMat = NumPyMatConvert::Ny8UC3ToMat(input);

    try{
        return ctbdPredictor.CTBDPredict(inputMat, matrixShape, height, width, stride,
                                         sectionPredictor, fileNameList, refineSavePath, segSavePath);
    }catch (const std::exception& e){
        std::cout << e.what() << std::endl;
        return CTBD::CTBD_LIST {};
    }

}

